﻿@namespace MudBlazor
@inherits MudTableBase
@using MudBlazor.Utilities
@typeparam T

@(ClearFilterCache()) @*Clear filtered items cache for this render*@

<div @attributes="UserAttributes" class="@Classname" style="@Style">
@if (Items != null || ServerData != null)
{
    <CascadingValue Value="TableContext" IsFixed="true">
        @if (ToolBarContent != null)
        {
            <MudToolBar Class="mud-table-toolbar">
                @ToolBarContent
            </MudToolBar>
        }
        @if (Context.SortLabels.Any())
        {
            <div Class="mud-table-smalldevices-sortselect">
                <CascadingValue Name="SubscribeToParentForm" Value="false" IsFixed>
                    <MudSelect Value="@Context.CurrentSortLabel" Label="@SortLabel" ValueChanged="@(v => Context.SetSortFunc(v, overrideDirectionNone: true))" T="MudTableSortLabel<T>">
                        @foreach (var label in Context.SortLabels)
                        {
                            <MudSelectItem Value="@label">@label.ChildContent</MudSelectItem>
                        }
                    </MudSelect>
                </CascadingValue>
            </div>
        }
        <div id="@_tableId" class="mud-table-container @TableContainerClass" style="@TableContainerStyle @(GetHorizontalScrollbarStyle())">
            <table class="@TableClassname" aria-label="@AriaLabel">
                @if (ColGroup != null)
                {
                    <colgroup>
                        @ColGroup
                    </colgroup>
                }
                @if (HeaderContent != null || Columns != null)
                {
                    <thead class="@HeadClassname">
                        @if (CustomHeader)
                        {
                            @HeaderContent
                        }
                        else
                        {
                            <MudTHeadRow Checkable="MultiSelection" SelectionChangeable="SelectionChangeable" Expandable="@(GroupBy?.Expandable ?? false)">
                                @if (HeaderContent != null)
                                {
                                    @HeaderContent
                                }

                                @if (Columns != null)
                                {
                                    @Columns(Def)
                                }
                            </MudTHeadRow>
                        }
                        @if (Loading)
                        {
                            <tr>
                                <th colspan="1000" class="@(CurrentPageItems.Any() || (LoadingContent is not null || LoadingContentBody is not null) ? "mud-table-loading" : "")">
                                    <MudProgressLinear Color="@LoadingProgressColor" Class="mud-table-loading-progress" Indeterminate="true" />
                                </th>
                            </tr>
                        }
                    </thead>
                }
                else if (Loading)
                {
                    <thead class="@HeadClassname">
                        <tr class="mud-table-row">
                            <th colspan="1000" class="@(CurrentPageItems.Any() || (LoadingContent is not null || LoadingContentBody is not null) ? "mud-table-loading" : "")">
                                <MudProgressLinear Color="@LoadingProgressColor" Class="mud-table-loading-progress" Indeterminate="true" />
                            </th>
                        </tr>
                    </thead>
                }
                <tbody class="mud-table-body">
                    @if(GroupBy != null)
                    {
                        @foreach (var group in GroupItemsPage)
                        {
                            <MudTableGroupRow @key="group.Key" T="T" GroupDefinition="GroupBy" Items="group"
                                              Checkable="MultiSelection" SelectionChangeable="SelectionChangeable"
                                              HeaderClass="@GroupHeaderClass" HeaderStyle="@GroupHeaderStyle" HeaderTemplate="@GroupHeaderTemplate"
                                              FooterClass="@GroupFooterClass" FooterStyle="@GroupFooterStyle" FooterTemplate="@GroupFooterTemplate" />
                        }
                    }
                    else
                    {
                        @if (CurrentPageItems != null && CurrentPageItems.Any())
                        {
                            var rowIndex = 0;
                            <MudVirtualize Enabled="@Virtualize" Items="@CurrentPageItems?.ToList()" OverscanCount="@OverscanCount" ItemSize="@ItemSize" Context="item">
                                @{
                                    var itemIndex = FilteredItems.ToList().IndexOf(item);
                                    string generatedRowId = itemIndex != -1 ? $"{_tableId}_row_{itemIndex}" : null;
                                    var rowClass = new CssBuilder(RowClass).AddClass(RowClassFunc?.Invoke(item, itemIndex)).Build();
                                    var rowStyle = new StyleBuilder().AddStyle(RowStyle).AddStyle(RowStyleFunc?.Invoke(item, itemIndex)).Build();
                                }
                                <MudTr Class="@rowClass" Style="@rowStyle" Item="item" @key="item" RowId="@generatedRowId"
                                        Checkable="MultiSelection" SelectionChangeable="SelectionChangeable" Editable="IsItemEditable(item)"
                                        Checked="@(IsCheckedRow(item))"
                                        CheckedChanged="((value) => OnRowCheckboxChanged(value, item))">

                                    @if ((!ReadOnly) && Editable && Equals(_editingItem, item))
                                    {
                                        <CascadingValue Value="@Validator" IsFixed="true">
                                            @if (RowEditingTemplate != null)
                                            {
                                                @RowEditingTemplate(item)
                                            }
                                            @if (Columns != null)
                                            {
                                                @Columns(item)
                                            }
                                        </CascadingValue>
                                    }
                                    else
                                    {
                                        if (RowTemplate != null)
                                        {
                                            @RowTemplate(item)
                                        }
                                        @if (Columns != null)
                                        {
                                            @Columns(item)
                                        }
                                    }
                                </MudTr>
                                @if (ChildRowContent != null)
                                {
                                    @ChildRowContent(item)
                                }
                                @{ rowIndex++; }
                            </MudVirtualize>
                        }
                    }
                    @if (!(CurrentPageItems is not null && CurrentPageItems.Any()))
                    {
                        if (Loading && LoadingContentBody != null)
                        {
                            @LoadingContentBody
                        }
                        else if (Loading ? LoadingContent != null : NoRecordsContent != null)
                        {                            
                            <tr>
                                <th colspan="1000" class="mud-table-empty-row">
                                    <div Class="my-3">
                                        @if(Loading)
                                        {
                                            @LoadingContent
                                        }
                                        else
                                        {
                                            @NoRecordsContent
                                        }
                                    </div>
                                </th>
                            </tr>    
                        }
                    }
                </tbody>
                @if (FooterContent != null || Columns != null)
                {
                    <tfoot class="@FootClassname">
                        @if (CustomFooter)
                        {
                            @FooterContent
                        }
                        else
                        {
                            <MudTFootRow Checkable="MultiSelection" SelectionChangeable="SelectionChangeable" Expandable="@(GroupBy?.Expandable ?? false)">
                                @if (FooterContent != null)
                                {
                                    @FooterContent
                                }
                                @if (Columns != null)
                                {
                                    @Columns(Def)
                                }
                            </MudTFootRow>
                        }
                    </tfoot>
                }
            </table>
        </div>
        @if (PagerContent != null)
        {
            <div class="mud-table-pagination">
                @PagerContent
            </div>
        }
    </CascadingValue>
}
</div>
@code
{
    // moved to code to avoid repeatedly code on markup block
    internal RenderFragment RenderRows(IEnumerable<T> source, string customClass = null, bool expandable = false)
    {
        var rowIndex = 0;

        RenderFragment rootNode =
            @<text>
                <MudVirtualize Enabled="@Virtualize" Items="@source?.ToList()" OverscanCount="@OverscanCount" ItemSize="@ItemSize" Context="item" ChildContent="@child()">
                </MudVirtualize>
            </text>;

         RenderFragment<T> child() => item =>
             @<text>
             @{
                 var itemIndexForId = FilteredItems.ToList().IndexOf(item);
                 string generatedRowId = itemIndexForId != -1 ? $"{_tableId}_row_{itemIndexForId}" : null;

                 var rowClass = new CssBuilder(RowClass).AddClass(RowClassFunc?.Invoke(item, itemIndexForId)).AddClass(customClass, !string.IsNullOrEmpty(customClass)).Build();
                 var rowStyle = new StyleBuilder().AddStyle(RowStyle).AddStyle(RowStyleFunc?.Invoke(item, itemIndexForId)).Build();
             }
             <MudTr Class="@rowClass" Style="@rowStyle" Item="item" @key="item" RowId="@generatedRowId" Checkable="MultiSelection" SelectionChangeable="SelectionChangeable" Editable="IsItemEditable(item)" Expandable="expandable"
                Checked="Context.Selection.Contains(item)" CheckedChanged="((value) => { var x = item; OnRowCheckboxChanged(value, x); })">
                @if ((!ReadOnly) && Editable && Equals(_editingItem, item))
                {
                    <CascadingValue Value="@Validator" IsFixed="true">
                        @if(RowEditingTemplate != null)
                        {
	                        @RowEditingTemplate(item)
                        }
                        @if (Columns != null)
                        {
                            @Columns(item)
                        }
                    </CascadingValue>
                }
                else
                {
                    if (RowTemplate != null)
                    {
	                    @RowTemplate(item)
                    }
                    @if (Columns != null)
                    {
                        @Columns(item)
                    }
                }
            </MudTr>
            @if (ChildRowContent != null)
            {
                @ChildRowContent(item)
            }
            @{rowIndex++;}
        </text>;

        return rootNode;
    }
}

